package com.wzl.mixed.controller;

import com.wzl.common.VkPublicResponse;
import com.wzl.common.exception.VkPublicException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;

import java.util.Optional;

/**
 * Optional类的使用
 *
 * @author weizhongli
 * @since 2022-09-21 17:09
 */
@Controller
@Slf4j
public class MpOptionalController {

    public static VkPublicResponse OptionalTest1(){
        //创建一个值为张三的String类型的Optional
        Optional<String> ofOptional = Optional.of("张三");
        String s = ofOptional.get();
        log.info(s);
        //如果我们用of方法创建Optional对象时，所传入的值为null，则抛出NullPointerException如下图所示
        //Optional<String> nullOptional = Optional.of(null);
        return new VkPublicResponse();
    }

    public static VkPublicResponse OptionalTest2(){
        //为指定的值创建Optional对象，不管所传入的值为null不为null，创建的时候都不会报错
        Optional<String> nullOptional = Optional.ofNullable(null);
        //Optional<String> nullOptional = Optional.ofNullable("lisi");
        //创建一个空的String类型的Optional对象
        Optional<String> emptyOptional = Optional.empty();
        String s = nullOptional.get();
        log.info(s);
        return new VkPublicResponse();
    }

    /**
     * 如果创建的Optional中有值存在，则返回此值，否则返回一个默认值
     */
    public static VkPublicResponse OptionalTest3(){
        Optional<String> stringOptional = Optional.of("张三");
        log.info(stringOptional.orElse("红红火火恍恍惚惚"));

        Optional<String> emptyOptional = Optional.empty();
        log.info(emptyOptional.orElse("李四"));
        return new VkPublicResponse();
    }

    /**
     * 如果创建的Optional中有值存在，则返回此值，否则返回一个由Supplier接口生成的值
     */
    public static VkPublicResponse OptionalTest4(){
        Optional<String> stringOptional = Optional.of("张三");
        log.info(stringOptional.orElseGet(() -> "zhangsan"));

        Optional<String> emptyOptional = Optional.empty();
        log.info(emptyOptional.orElse("orElseGet"));
        return new VkPublicResponse();
    }

    /**
     * 如果创建的Optional中有值存在，则返回此值，否则抛出一个由指定的Supplier接口生成的异常
     */
    public static VkPublicResponse OptionalTest5() throws VkPublicException {
        Optional<String> stringOptional = Optional.of("张三");
        log.info(stringOptional.orElseThrow(VkPublicException::new));

        Optional<String> emptyOptional = Optional.empty();
        log.info(emptyOptional.orElseThrow(VkPublicException::new));

        return new VkPublicResponse();
    }

    /**
     * filter
     * 如果创建的Optional中的值满足filter中的条件，则返回包含该值的Optional对象，否则返回一个空的Optional对象
     */
    public static VkPublicResponse OptionalTest6(){
        Optional<String> stringOptional = Optional.of("zhangsan");
        log.info(stringOptional.filter(e -> e.length() > 5).orElse("王五"));
        stringOptional = Optional.empty();
        log.info(stringOptional.filter(e -> e.length() > 5).orElse("lisi"));

        return new VkPublicResponse();
    }

    /**
     * map
     * 如果创建的Optional中的值存在，对该值执行提供的Function函数调用
     */
    public static VkPublicResponse OptionalTest7(){
        //map方法执行传入的lambda表达式参数对Optional实例的值进行修改,修改后的返回值仍然是一个Optional对象
        Optional<String> stringOptional = Optional.of("zhangsan");
        System.out.println(stringOptional.map(e -> e.toUpperCase()).orElse("失败"));

        stringOptional = Optional.empty();
        System.out.println(stringOptional.map(e -> e.toUpperCase()).orElse("失败"));

        return new VkPublicResponse();
    }

    /**
     * flagMap
     * 如果创建的Optional中的值存在，就对该值执行提供的Function函数调用，返回一个Optional类型的值，否
     * 则就返回一个空的Optional对象.flatMap与map（Funtion）方法类似，区别在于flatMap中的mapper返回
     * 值必须是Optional，map方法的mapping函数返回值可以是任何类型T。调用结束时，flatMap不会对结果
     * 用Optional封装
     */
    public static VkPublicResponse OptionalTest8(){
        //map方法中的lambda表达式返回值可以是任意类型，在map函数返回之前会包装为Optional。
        //但flatMap方法中的lambda表达式返回值必须是Optionl实例
        Optional<String> stringOptional = Optional.of("zhangsan");
        System.out.println(stringOptional.flatMap(e -> Optional.of("lisi")).orElse("失败"));

        stringOptional = Optional.empty();
        System.out.println(stringOptional.flatMap(e -> Optional.empty()).orElse("失败"));
        return new VkPublicResponse();
    }

    /**
     * ifPresent
     */
    public static VkPublicResponse OptionalTest9(){
        //ifPresent方法的参数是一个Consumer的实现类，Consumer类包含一个抽象方法，该抽象方法对传入的值进行处理，只处理没有返回值。
        Optional<String> stringOptional = Optional.of("zhangsan");
        stringOptional.ifPresent(e-> System.out.println("我被处理了。。。"+e));
        return new VkPublicResponse();
    }

    public static void main(String[] args) {
        //OptionalTest1();
        //OptionalTest2();
        //OptionalTest3();
//        OptionalTest4();
        //OptionalTest5();
        //OptionalTest6();
        //OptionalTest7();
        //OptionalTest8();
        OptionalTest9();

        //String table_abc = String.format("%s_%02d", "table_ABC", abs(Math.floorMod(120, 7)));
        //int fixAccNumFlag = 7 & 2;
//        Map<Long, VkSmbmsUser> mapBalanceTypeName = new HashMap<>(16);
//        int size = mapBalanceTypeName.size();
//        log.info(String.valueOf(size));
    }

}
